#ifndef STDAFX_H
#define STDAFX_H

// Windows
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <io.h>

// DirectX
#ifdef _DEBUG
#define D3D_DEBUG_INFO
#endif
#include <d3d9.h>
#include <d3dx9.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

// BASS
#include "bass.h"

// Boost
#include <boost/array.hpp>
#include <boost/utility.hpp>	// boost::noncopyable
#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include<boost/enable_shared_from_this.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/lexical_cast.hpp>
#pragma warning(disable:4996)	//'std::char_traits<char>::copy' was declared deprecated
#include <boost/format.hpp>
#pragma warning(default:4996)
#include <boost/operators.hpp>
#include <boost/functional/hash.hpp>
#include <boost/algorithm/string.hpp>

// Stl
#include <limits>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <vector>
#include <stack>
#include <list>
#include <exception>
#include <cassert>
// TODO: remove ctime dependency, used only in Random
#include <ctime>
//#include <cstdio> // used in Filesystem

// Memory manager
#ifdef _DEBUG
#include "mmgr.h"
#endif

// Common types
typedef long long int64;
typedef unsigned long long uint64;
typedef int int32;
typedef unsigned int uint32;
typedef unsigned int uint;
typedef short int16;
typedef unsigned short uint16;
typedef char int8;  
typedef unsigned char uint8;
typedef unsigned char byte;

// Float utils
const float infinity = std::numeric_limits<float>::infinity();
const float epsilon = 0.00001f;
const float pi = 3.14159265f;
#define FCMP(a, b) (fabs((a) - (b)) < epsilon)

inline float radians(float degrees)
{
	return (degrees / 360.0f) * 2.0f * pi;
}

template <typename T>
inline T lerp(const T& a, const T& b, float t)
{
	return a * (1.0f - t) + b * t;
}

template <typename T>
inline T smoothstep(const T& a, const T& b, float t)
{
	if(t < 0.0f)
		return a;
	if(t > 1.0f)
		return b;
	return lerp(a, b, t * t * (3.0f - 2.0f * t));
}

template <typename T>
inline T smootherstep(const T& a, const T& b, float t)
{
	if(t < 0.0f)
		return a;
	if(t > 1.0f)
		return b;
	return smoothstep(a, b, t * t * (3.0f - 2.0f * t));
}

// Format macro
#define FORMAT(fmt, val) (str(boost::format(fmt) val))

// Type bounds
#define MIN_INT8 ((int8) 0x80)
#define MAX_INT8 ((int8) 0x7f)
#define MAX_UINT8 ((uint8) 0xff)

#define MIN_INT16 ((int16) 0x8000)
#define MAX_INT16 ((int16) 0x7fff)
#define MAX_UINT16 ((uint16) 0xffff)

#define MIN_INT32 ((int32) 0x80000000)
#define MAX_INT32 ((int32) 0x7fffffff)
#define MAX_UINT32 ((uint32) 0xffffffff)

#define MIN_INT64 ((int64) 0x8000000000000000LL)
#define MAX_INT64 ((int64) 0x7fffffffffffffffLL)
#define MAX_UINT64 ((uint64) 0xffffffffffffffffULL)

#endif
